//
//  YJFPSLabel.swift
//  YJWeiBo
//
//  Created by Jim1024 on 2017/1/23.
//  Copyright © 2017年 Jim1024. All rights reserved.
//

import UIKit

private var kFPSViewKey = "FPSViewKey"

// MARK: - 扩展 UIView, 添加属性(利用runtime关联对象)
public extension UIView {
    var fpsView: YJFPSLabel? {
        get {
            if let fps = objc_getAssociatedObject(self, &kFPSViewKey) as? YJFPSLabel {
                return fps
            } else {
                let fps = YJFPSLabel()
                self.addSubview(fps)
                self.fpsView = fps
                return fps
            }
        }
        
        set {
            objc_setAssociatedObject(self, &kFPSViewKey, newValue, objc_AssociationPolicy.OBJC_ASSOCIATION_RETAIN_NONATOMIC)
        }
    }
    
    /// 在自定位置显示
    func showFPS(_ origin: CGPoint) {
        fpsView?.frame.origin = origin
    }
    
    /// 在左上角显示
    func showFPS() {
        showFPS(CGPoint.zero)
    }
    
    /// 在控件中心显示
    func showFPSInCenter() {
        let center = CGPoint(x: frame.width * 0.5, y: frame.height * 0.5)
        fpsView?.center = center
    }
}

// MARK: - YJFPSLabel,显示view的帧率
open class YJFPSLabel: UILabel {
    
    // fpsLabel的大小
    fileprivate let fpsSize = CGSize(width: 70, height: 20)
    // 帧数的 Font
    fileprivate var textFont: UIFont? = UIFont.systemFont(ofSize: 14)
    // FPS文字的 Font
    fileprivate var subTextFont: UIFont? = UIFont.systemFont(ofSize: 12)
    
    fileprivate var link: CADisplayLink?
    
    // 上一次计算帧数的时间
    fileprivate var lastTime: TimeInterval = 0
    
    // 一秒内调用了的次数
    fileprivate var count = 0
    
    // FPS 文字
    fileprivate let fpsText = "FPS"
    
    override init(frame: CGRect) {
        var frame = frame
        // 判断外面调用的时候是否有传frame进来
        if frame.size.width == 0 && frame.size.height == 0 {
            frame.size = fpsSize
        }
        super.init(frame: frame)
        
        layer.cornerRadius = 5
        layer.masksToBounds = true
        
        textAlignment = NSTextAlignment.center
        backgroundColor = UIColor(white: 0, alpha: 0.7)
        
        textFont = UIFont(name: "Menlo", size: 14)
        if let _ = textFont {
            subTextFont = UIFont(name: "Menlo", size: 12)
        } else {
            textFont = UIFont(name: "Courier", size: 14)
            subTextFont = UIFont(name: "Courier", size: 12)
        }
        
        // 创建 CADisplayLink 并加入 NSRunLoop
        link = CADisplayLink(target: self, selector: #selector(tick(_:)))
        link?.add(to: RunLoop.main, forMode: RunLoopMode.commonModes)
    }
    
    required public init?(coder aDecoder: NSCoder) {
        fatalError("init(coder:) has not been implemented")
    }
    
    deinit {
        link?.invalidate()
        link = nil
    }
    
    open override func sizeThatFits(_ size: CGSize) -> CGSize {
        return fpsSize
    }
    
    // 每帧调用
    @objc fileprivate func tick(_ link: CADisplayLink) {
        // 判断是否是第一次调用,第一次调用,设置 上一次计算帧数的时间
        if lastTime == 0 {
            lastTime = link.timestamp
            return
        }
        
        // 调用次数++
        count += 1
        
        // 计算距离上次计算帧数的时间
        let delta = link.timestamp - lastTime
        
        if delta < 1 {
            return // 小于一秒 return
        }
        
        // 到一秒钟, 计算帧数
        let fps = Double(count) / delta
        
        // 赋值最后一次计算帧数时间
        lastTime = link.timestamp
        
        // 清空帧数
        count = 0
        
        // 计算比例,显示颜色
        let progress = fps / 60.0
        
        // 计算 帧数 颜色
        let color = UIColor(hue: CGFloat(0.27 * (progress - 0.2)), saturation: 1, brightness: 0.9, alpha: 1)
        
        let fpsString = String(format: "%.1f", arguments: [fps])
        
        // 设置内容
        let content = "\(fpsString) \(fpsText)"
        
        // 创建属性文本
        let attr = NSMutableAttributedString(string: "\(content)")
        
        // 添加属性
        let numRange = NSRange(location: 0, length: attr.length - fpsText.characters.count)
        attr.addAttribute(NSForegroundColorAttributeName, value: color, range: numRange)
        attr.addAttribute(NSFontAttributeName, value: textFont!, range: numRange)
        
        let fpsRange = (content as NSString).range(of: fpsText)
        attr.addAttribute(NSForegroundColorAttributeName, value: UIColor.white, range: fpsRange)
        attr.addAttribute(NSFontAttributeName, value: subTextFont!, range: fpsRange)
        
        attributedText = attr
    }
}
